package clock.socoolby.com.clock.widget.textview;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Shader;
import android.text.TextPaint;
import android.text.style.ReplacementSpan;
import android.util.AttributeSet;
import android.util.Log;
import androidx.annotation.Nullable;

import java.util.Random;

public class DigitTextView extends android.support.v7.widget.AppCompatTextView {
    public static final String Tag=DigitTextView.class.getSimpleName();

    float baseLineDown=0;

    private LinearGradient mLinearGradient;

    private boolean isLinearGradientAble=false;

    private int shadowType=0;//0:不设置，1：阴影，2:浮雕

    private int[] linearGradientColors;

    int textWidth=0;

    public DigitTextView(Context context) {
        super(context);
    }

    public DigitTextView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public DigitTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public void setBaseLineDown(float baseLineDown) {
        this.baseLineDown = baseLineDown;
    }

    float[]  pos = {0f,0.2f,0.4f,0.5f,0.6f,0.8f,1.0f};

    boolean isLinearGradientPosAble=false;

    public void setLinearGradientRandom(boolean able){
        if(able){
            linearGradientColors= new int[]{roundColor(), roundColor(), roundColor(), roundColor(), roundColor(), roundColor(), roundColor()};
            isLinearGradientPosAble=rand.nextBoolean();
        }
        setLinearGradientAble(able);
        setShadowType(rand.nextInt(3));
    }

    public void setLinearGradientAble(boolean able){
        isLinearGradientAble=able;
        Paint mTextPaint=getPaint();
        if(isLinearGradientAble){
            setLinearGradient(linearGradientColors);
        }else{
            mTextPaint.setShader(null);
        }
    }

    public void setLinearGradient(int[] colors){
        Paint mTextPaint=getPaint();
        if(isLinearGradientPosAble&&colors.length==pos.length)
            mLinearGradient = new LinearGradient(0, 0, getWidth(), getHeight(), colors , pos, Shader.TileMode.CLAMP);
        else
            mLinearGradient = new LinearGradient(0, 0, getWidth(), 0,colors, null, Shader.TileMode.CLAMP);
        mTextPaint.setShader(mLinearGradient);
    }

    public void setShadowType(int shadowType){
        this.shadowType=shadowType;
        switch (shadowType){
            case 1://阴影效果
                setShadowLayer(4, 10, 10, Color.BLACK);
                break;
            case 2://浮雕效果
                setShadowLayer(1, 0.5f, 0.5f, Color.argb(200,204,204,204));
                break;
            default:
                setShadowLayer(0,0,0,getPaint().getColor());
        }
    }

    public int getShadowType(){
        return shadowType;
    }

    public boolean isLinearGradientAble(){
        return isLinearGradientAble;
    }

    public boolean isLinearGradientPosAble() {
        return isLinearGradientPosAble;
    }

    public int[] getLinearGradientColors() {
        return linearGradientColors;
    }

    public void setLinearGradientPosAble(boolean linearGradientPosAble) {
        isLinearGradientPosAble = linearGradientPosAble;
    }

    public void setLinearGradientColors(int[] linearGradientColors) {
        this.linearGradientColors = linearGradientColors;
    }

    protected void onDraw(Canvas canvas) {
        int color = getCurrentTextColor();

        Paint mTextPaint=getPaint();

        mTextPaint.setColor(color);

        CharSequence textToDraw=getText();

        Paint.FontMetricsInt fm=mTextPaint.getFontMetricsInt();

        int baseCharWidth= getCharWidth("8",mTextPaint);
        int flagCharwidth=getCharWidth(":",mTextPaint);
        int textHight=-fm.descent  - fm.ascent;
        int smallTextHight=0;
        int smallCharWidth=0;
        Paint smallCharPaint=null;

        int textLength=textToDraw.length();
        int textSmallSpan=0;

        if(textLength>4){
            textWidth=baseCharWidth*4+flagCharwidth;
        }

        if(textLength>7){
            float fontScale = getResources().getDisplayMetrics().scaledDensity;
            smallCharPaint = getCustomTextPaint(mTextPaint,mTextPaint.getTextSize()/fontScale*4/5);
            smallCharWidth=getCharWidth("8",smallCharPaint);
            fm=smallCharPaint.getFontMetricsInt();
            smallTextHight=-fm.descent  - fm.ascent;
            textSmallSpan=smallCharWidth*2;
        }

        float startX=(getWidth()-textWidth-textSmallSpan)/2;
        float startY=(getHeight()+textHight)/2;

        for(int i=0;i<textLength;i++){
            String c=String.valueOf(textToDraw.charAt(i));
            if(i<5){
                if(i==2){
                    canvas.drawText(c, startX, startY+baseLineDown, mTextPaint);
                    startX+=flagCharwidth;
                }else{
                    int charWidth= getCharWidth(c,mTextPaint);
                    canvas.drawText(c, startX+(baseCharWidth-charWidth)/2, startY+baseLineDown, mTextPaint);
                    startX+=baseCharWidth;
                }
            }else if(i==5) {
                startX+=smallCharWidth/2;
            } else {
                    float centerY=(getHeight()+smallTextHight)/2;
                    centerY=centerY+(startY-centerY)/2+smallCharPaint.getFontMetrics().descent;
                    canvas.drawText(c, startX, centerY+baseLineDown, smallCharPaint);
                    startX+=smallCharWidth;
                    //Log.d(Tag,"view hight:"+getHeight()+"\t startY:"+startY+"\t text hight:"+textHight+"small text hight:"+smallTextHight);
             }
        }
    }

    /**
     * 使TextView中不同大小字体垂直居中
     */
    public static class DigitSpan extends ReplacementSpan {
        private int fontSizeSp;    //字体大小sp

        private float beseLineDown=0;

        public DigitSpan(){
        }

        @Override
        public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) {

            String text1 = text.subSequence(start, end).toString();
            //Log.d("DigitSpan","getSize  text:"+text+"\tstart:"+start+"\tend:"+end+"\tsubStr:"+text1);
            //Paint p = getCustomTextPaint(paint);
            return (int) getCharWidth("8",paint)*text1.length();
        }

        @Override
        public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) {
            String text1 = text.subSequence(start, end).toString();
            //Log.d("DigitSpan","draw  text:"+text+"\tstart:"+start+"\tend:"+end+"\tsubStr:"+text1);
            Paint p = getCustomTextPaint(paint);
            Paint.FontMetricsInt fm = p.getFontMetricsInt();
            int baseCharWitch= getCharWidth("8",paint);
            int currentCharWidth,moveWidthX;
            for(int i=0;i<text1.length();i++) {
                String currentChar=String.valueOf(text1.charAt(i));
                currentCharWidth= getCharWidth(currentChar,paint);
                moveWidthX=baseCharWitch*i+(baseCharWitch-currentCharWidth)/2;
                canvas.drawText(currentChar, x+moveWidthX, y - ((y + fm.descent + y + fm.ascent) / 2 - (bottom + top) / 2)+beseLineDown, p);    //此处重新计算y坐标，使字体居中
            }
        }

        private TextPaint getCustomTextPaint(Paint srcPaint) {
            TextPaint paint = new TextPaint(srcPaint);
            //paint.setTextSize(ViewUtils.getSpPixel(mContext, fontSizeSp));   //设定字体大小, sp转换为px
            return paint;
        }

        public void setBeseLineDown(float beseLineDown){
            this.beseLineDown=beseLineDown;
        }

    }

    public static class DigitFlagSpan extends ReplacementSpan {
        private float beseLineDown=0;

        public DigitFlagSpan(){
        }

        @Override
        public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) {
            String text1 = text.subSequence(start, end).toString();
            return (int) getCharWidth(":",paint);
        }

        @Override
        public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) {
            String text1 = text.subSequence(start, end).toString();
            Paint.FontMetricsInt fm = paint.getFontMetricsInt();
            canvas.drawText(text1, x, y - ((y + fm.descent + y + fm.ascent) / 2 - (bottom + top) / 2)+beseLineDown, paint);    //此处重新计算y坐标，使字体居中
        }

        public void setBeseLineDown(float beseLineDown){
            this.beseLineDown=beseLineDown;
        }
    }

    public static class DigitSmallSpan extends ReplacementSpan {
        private float fontSizeSp;    //字体大小sp
        private float beseLineDown=0;

        public DigitSmallSpan(){
        }

        @Override
        public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) {

            String text1 = text.subSequence(start, end).toString();
            //Log.d("DigitSpan","getSize  text:"+text+"\tstart:"+start+"\tend:"+end+"\tsubStr:"+text1);
            fontSizeSp=paint.getTextSize()/2;
            Paint p = getCustomTextPaint(paint,fontSizeSp);
            return (int) getCharWidth("8",p)*text1.length();
        }

        int currentCharWidth,moveWidthX;
        String currentChar;
        @Override
        public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) {
            String text1 = text.subSequence(start, end).toString();
            if(text1.length()<=1)
                return;
            //Log.d("DigitSpan","draw  text:"+text+"\tstart:"+start+"\tend:"+end+"\tsubStr:"+text1);
            Paint.FontMetricsInt fmBefor=paint.getFontMetricsInt();
            Paint p = getCustomTextPaint(paint,fontSizeSp);
            Paint.FontMetricsInt fm = p.getFontMetricsInt();
            int baseCharWitch= getCharWidth("8",p);
            for(int i=1;i<text1.length();i++) {
                currentChar=String.valueOf(text1.charAt(i));
                currentCharWidth= getCharWidth(currentChar,paint);
                moveWidthX=baseCharWitch*i+(baseCharWitch-currentCharWidth)/2;
                //canvas.drawText(currentChar, x+moveWidthX, bottom+fm.ascent, p);    //此处重新计算y坐标，使字体居中
                canvas.drawText(currentChar, x+moveWidthX, bottom-fmBefor.descent+beseLineDown, p);    //此处重新计算y坐标，使字体居中
            }
        }


        public void setBeseLineDown(float beseLineDown){
            this.beseLineDown=beseLineDown;
        }
    }

    private static TextPaint getCustomTextPaint(Paint srcPaint,float fontSizeSp) {
        TextPaint paint = new TextPaint(srcPaint);
        paint.setTextSize(fontSizeSp);   //设定字体大小, sp转换为px
        return paint;
    }


    public static class SuperSubSpan extends ReplacementSpan
    {

        public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm)
        {
            text = text.subSequence(start, end);
            String[] parts = text.toString().split(",");
            Paint p = getSuperSubPaint(paint);
            return (int) Math.max(p.measureText(parts[0]), p.measureText(parts[1]));
        }

        private static TextPaint getSuperSubPaint(Paint src)
        {
            TextPaint paint = new TextPaint(src);
            paint.setTextSize(src.getTextSize() / 2.5f);
            return paint;
        }

        @Override
        public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint)
        {
            text = text.subSequence(start, end);
            String[] parts = text.toString().split(",");

            Paint p = getSuperSubPaint(paint);

            float width1 = p.measureText(parts[0]);
            float width2 = p.measureText(parts[1]);
            float maxWidth = Math.max(width1, width2);

            canvas.drawText(parts[0], x + (maxWidth - width1), y - (bottom - top) / 3f, p);
            canvas.drawText(parts[1], x + (maxWidth - width2), y + (bottom - top) / 10f, p);
        }
    }

    static Random rand=new Random();
    public static int roundColor(){
        int alpha = 200;
        int r = rand.nextInt(255);
        int g = rand.nextInt(255);
        int b = rand.nextInt(255);
        return alpha << 24 | r << 16 | g << 8 | b;
    }

    private static int getCharWidth(String str, Paint paint){
        return (int)paint.measureText(str);
    }
}
